<?php
include_once dirname(dirname(__FILE__)) . '/zingme-sdk/BaseZingMe.php';
include_once dirname(dirname(__FILE__)) . '/zingme-sdk/ZME_Me.php';
include_once dirname(dirname(__FILE__)) . '/zingme-sdk/ZME_User.php';
class SGN_ZingMe
{
    /*private static $_config;
    private static $_zm_Me;*/
    public function initialZingMe ($userID, $zingMeParam)
    {
        //pr($userID);
        // header("Location: http://beta.union.zing.vn/gunny/friendlist/friend");
        $config = array('appname' => $zingMeParam['appname'], 'apikey' => $zingMeParam['apikey'], 'secretkey' => $zingMeParam['secretkey'], 'env' => $zingMeParam['env']);
        $zm_Me = new ZME_Me($config);
        $state = rand(1, 10000000);
        $url = $zm_Me->getUrlAuthorized($zingMeParam['redirectUri'] . '?env=' . $zingMeParam['envRedirect'] . '&userid=' . $userID, $state);
        header("Location: " . $url);
    }
    public function getFriendFromZingMe ($authorization_code, $userID, $zingMeParam, $startElement = 0, $endElement = 0, $isJsonRequest = false, $useCache = true)
    {
        $timeStart = microtime(true);
        $config = array('appname' => $zingMeParam['appname'], 'apikey' => $zingMeParam['apikey'], 'secretkey' => $zingMeParam['secretkey'], 'env' => $zingMeParam['env']);
        $zm_Me = new ZME_Me($config);
        $error = array();
        $error['error']['type'] = '';
        $error['error']['url'] = '';
        $this->_model = Application_Model_Armory_Gunny::factory('General');
        //$authorization_code = urldecode($authorization_code);
        try {
            //$access_token_data = $this->_model->getZingMeAccessToken($userID);
            if (! $access_token_data) {
                $access_token_data = $zm_Me->getAccessTokenFromCode($authorization_code);
                $this->_model->setZingMeAccessToken($userID, $access_token_data);
            }
            SGN_Log::writeLog(__CLASS__, __FUNCTION__, 'get access token time:' . (microtime(true) - $timeStart) * 1000);
            SGN_Log::writeLog(__CLASS__, __FUNCTION__, $authorization_code);
        } catch (ZingMeApiException $Ze) {
            SGN_Log::writeLog(__CLASS__, __FUNCTION__ . 'Error', 'User: ' . $userID);
            $userName = SGN_SSO::validate(SGN_Application::getConfig('sgn', 'sso'), false);
            SGN_Log::writeLog(__CLASS__, __FUNCTION__ . 'Error', 'UserName: ' . $userName);
            SGN_Log::writeLog(__CLASS__, __FUNCTION__ . 'Error', 'IP: ' . $_SERVER['REMOTE_ADDR']);
            SGN_Log::writeLog(__CLASS__, __FUNCTION__ . 'Error', date('H:i:s d-m', time()) . ' - error: ' . $Ze);
            SGN_Log::writeLog(__CLASS__, __FUNCTION__ . 'Error', ' - authorization_code: ' . $authorization_code);
            if ($Ze->getErrType() === - 1) {
                SGN_Log::writeLog(__CLASS__, __FUNCTION__ . 'Error', date('H:i:s d-m', time()) . ' - error: ' . $Ze->getErrType());
                $state = rand(1, 10000000);
                $url = $zm_Me->getUrlAuthorized($zingMeParam['redirectUri'] . '?env=' . $zingMeParam['envRedirect'] . '&userid=' . $userID . "&update=true", $state);
                SGN_Log::writeLog(__CLASS__, __FUNCTION__, $authorization_code);
                if ($isJsonRequest) {
                    $error['error']['type'] = 'authorization code error';
                    $error['error']['url'] = $url;
                    return $error;
                }
                echo "
                <script type=\"text/javascript\">
                    document.domain = 'zing.vn';
                	tb_show(\"Sign in\",\"$url&KeepThis=true&TB_iframe=true&height=350&width=520\");
				</script>";
            } else {
                $error['error']['type'] = 'request error';
                $error['error']['msg'] = $Ze->getMessage();
                return $error;
            }
        }
        if ($access_token_data != null) {
            $access_token = $access_token_data['access_token'];
        }
        try {
            SGN_Log::writeLog(__CLASS__, __FUNCTION__, 'get zingme info - input:' . $access_token);
            try {
                //$me = $zm_Me->getInfo($access_token);
            } catch (ZingMeApiException $Ze) {
                SGN_Log::writeLog(__CLASS__, __FUNCTION__ . 'Error', 'User: ' . $userID);
                SGN_Log::writeLog(__CLASS__, __FUNCTION__ . 'Error', date('H:i:s d-m', time()) . ' - error: ' . $Ze);
                SGN_Log::writeLog(__CLASS__, __FUNCTION__ . 'Error', 'access_token: ' . $access_token);
                if ($Ze->getCode() === - 13 || $Ze->getCode() === - 12) {
                    try {
                        $access_token_data = $zm_Me->getAccessTokenFromCode($authorization_code);
                        $this->_model->setZingMeAccessToken($userID, $access_token_data);
                        $access_token = $access_token_data['access_token'];
                    } catch (ZingMeApiException $Ze) {
                        SGN_Log::writeLog(__CLASS__, __FUNCTION__ . 'Error', date('H:i:s d-m', time()) . ' - error: ' . $Ze->getErrMsg());
                        SGN_Log::writeLog(__CLASS__, __FUNCTION__ . 'Error', ' - authorization_code: ' . $authorization_code);
                        if ($Ze->getErrType() === - 1) {
                            $state = rand(1, 10000000);
                            $url = $zm_Me->getUrlAuthorized($zingMeParam['redirectUri'] . '?env=' . $zingMeParam['envRedirect'] . '&userid=' . $userID . "&update=true", $state);
                            SGN_Log::writeLog(__CLASS__, __FUNCTION__, $authorization_code);
                            if ($isJsonRequest) {
                                $error['error']['type'] = 'authorization code error';
                                $error['error']['url'] = $url;
                                return $error;
                            }
                            echo "
                <script type=\"text/javascript\">
                    document.domain = 'zing.vn';
                	tb_show(\"Sign in\",\"$url&KeepThis=true&TB_iframe=true&height=350&width=520\");
				</script>";
                        } else {
                            $error['error']['type'] = 'request error';
                            return $error;
                        }
                    }
                } else {
                    $error['error']['type'] = 'request error';
                    return $error;
                }
            }
            $friends = $this->_model->getZingMeFriendID($userID, $userCache);
            
            if (! $friends) {
            	$friends = $zm_Me->getFriends($access_token);
                $this->_model->setZingMeFriendID($userID, $friends, 'notsave');
            }
            SGN_Log::writeLog(__CLASS__, __FUNCTION__, 'get zingme friend id time: ' . (microtime(true) - $timeStart) * 1000);
            $uids = array();
            if (count($friends) >= $startElement) {
                for ($i = 0; $i < count($friends); $i ++) {
                    if ($i >= $startElement && $i <= $endElement) {
                        $uids[] = $friends[$i];
                        SGN_Log::writeLog(__CLASS__, __FUNCTION__, $uids);
                    }
                }
            }
            
            $zm_User = new ZME_User($config);
            $users = array();
            $result = array();
            if (is_array($uids)) {
                $getUidPart = array();
                foreach ($uids as $uid) {
                    $userInfo = $this->_model->getZingMeUserInfo($uid);
                    if (! $userInfo) {
                        $getUidPart[] = $uid;
                    } else {
                        $users[] = $userInfo;
                    }
                }
            }
            if (count($getUidPart)) {
                $user = $zm_User->getInfo($access_token, $getUidPart, $fields = "id,username,displayname,tinyurl,profile_url,gender");
            }
            
            if (count($user)) {
                foreach ($user as $userData) {
                    $this->_model->setZingMeUserInfo($userData);
                }
                $users = array_merge($users, $user);
            }
            $result['users'] = $users;
            $result['error'] = $error['error'];
            SGN_Log::writeLog(__CLASS__, __FUNCTION__, 'Output: ' . count($users));
            SGN_Log::writeLog(__CLASS__, __FUNCTION__, date('H:i:s d-m', time()) . ":" . 'total time = ' . (microtime(true) - $timeStart) * 1000);
            
            $allFriendCount = count($friends);
            $hasNext = $endElement >= $allFriendCount ? false : true;
            $result['moreInfo'] = array('hasNext' => $hasNext, 'allFriendCount' => $allFriendCount);
            return $result;
        } catch (ZingMeApiException $Ze) {
            SGN_Log::writeLog(__CLASS__, __FUNCTION__ . 'Error', 'User: ' . $userID);
            SGN_Log::writeLog(__CLASS__, __FUNCTION__, 'Output: ' . $Ze);
            $error['error']['type'] = 'request error';
            return $error;
        }
    }
    public function getFriendFromZingMeBySignedRequest ($signedrequest, $userID, $zingMeParam, $startElement = 0, $endElement = 0)
    {
        $timeStart = microtime(true);
        $config = array('appname' => $zingMeParam['appname'], 'apikey' => $zingMeParam['apikey'], 'secretkey' => $zingMeParam['secretkey'], 'env' => $zingMeParam['env']);
        $zm_Me = new ZME_Me($config);
        $error = array();
        $error['error']['type'] = '';
        $error['error']['url'] = '';
        $this->_model = Application_Model_Armory_Gunny::factory('General');
        try {
            $access_token_data = $this->_model->getZingMeAccessToken($userID);
            if (! $access_token_data) {
                $access_token = $zm_Me->getAccessTokenFromSignedRequest($signedrequest);
                $access_token_data['expires'] = 7200;
                $access_token_data['access_token'] = $access_token;
                $this->_model->setZingMeAccessToken($userID, $access_token_data);
            }
        } catch (ZingMeApiException $Ze) {
            SGN_Log::writeLog(__CLASS__, __FUNCTION__, 'Error: ' . $Ze->getErrMsg());
            SGN_Log::writeLog(__CLASS__, __FUNCTION__, 'Input: ' . $signedrequest);
            $state = rand(1, 10000000);
            $url = $zm_Me->getUrlAuthorized($zingMeParam['redirectUri'] . '?env=' . $zingMeParam['envRedirect'] . '&userid=' . $userID . "&update=true", $state);
            $error['error']['type'] = 'authorization code error';
            $error['error']['url'] = $url;
            return $error;
        }
        if ($access_token_data != null) {
            if (count($access_token_data) == 2) {
                $access_token = $access_token_data['access_token'];
            } else {
                $access_token = $access_token_data;
            }
        }
        try {
            try {
                $me = $zm_Me->getInfo($access_token);
            } catch (ZingMeApiException $Ze) {
                if ($Ze->getCode() === - 13 || $Ze->getCode() === - 12) {
                    $access_token = $zm_Me->getAccessTokenFromSignedRequest($signedrequest);
                    $access_token_data['expires'] = 7200;
                    $access_token_data['access_token'] = $access_token;
                    $this->_model->setZingMeAccessToken($userID, $access_token_data);
                } else {
                    $error['error']['type'] = 'request error';
                    return $error;
                }
            }
            $friends = $this->_model->getZingMeFriendID($userID);
            if (! $friends) {
                $friends = $zm_Me->getFriends($access_token);
                $this->_model->setZingMeFriendID($userID, $friends, 'notsave');
            }
            SGN_Log::writeLog(__CLASS__, __FUNCTION__, 'get zingme friend id time: ' . (microtime(true) - $timeStart) * 1000);
            $uids = array();
            if (count($friends) >= $startElement) {
                for ($i = 0; $i < count($friends); $i ++) {
                    if ($i >= $startElement && $i <= $endElement) {
                        $uids[] = $friends[$i];
                        SGN_Log::writeLog(__CLASS__, __FUNCTION__, $uids);
                    }
                }
            }
            $zm_User = new ZME_User($config);
            $users = array();
            if (is_array($uids)) {
                $getUidPart = array();
                foreach ($uids as $uid) {
                    $userInfo = $this->_model->getZingMeUserInfo($uid);
                    if (! $userInfo) {
                        $getUidPart[] = $uid;
                    } else {
                        $users[] = $userInfo;
                    }
                }
            }
            if (count($getUidPart)) {
                $user = $zm_User->getInfo($access_token, $getUidPart, $fields = "id,username,displayname,tinyurl,profile_url,gender");
            }
            if (count($user)) {
                foreach ($user as $userData) {
                    $this->_model->setZingMeUserInfo($userData);
                }
                $users = array_merge($users, $user);
            }
            $users['error'] = $error['error'];
            SGN_Log::writeLog(__CLASS__, __FUNCTION__, date('H:i:s d-m', time()) . ":" . 'total time = ' . (microtime(true) - $timeStart) * 1000);
            return $users;
        } catch (ZingMeApiException $Ze) {
            SGN_Log::writeLog(__CLASS__, __FUNCTION__, 'Input: ' . $signedrequest);
            SGN_Log::writeLog(__CLASS__, __FUNCTION__, 'Output: ' . $Ze);
            $error['error']['type'] = 'request error';
            return $error;
        }
    }
    public function getFriendFromZingMeByAccessToken ($access_token, $userID, $zingMeParam, $startElement = 0, $endElement = 0, $friends)
    {
        $timeStart = microtime(true);
        $config = array('appname' => $zingMeParam['appname'], 'apikey' => $zingMeParam['apikey'], 'secretkey' => $zingMeParam['secretkey'], 'env' => $zingMeParam['env']);
        $zm_Me = new ZME_Me($config);
        //$authorization_code = urldecode($authorization_code);
        try {
            SGN_Log::writeLog(__CLASS__, __FUNCTION__, 'get zingme info - input:' . $access_token);
            SGN_Log::writeLog(__CLASS__, __FUNCTION__, 'get zingme friend id time: ' . (microtime(true) - $timeStart) * 1000);
            $uids = array();
            if (count($friends) >= $startElement) {
                for ($i = 0; $i < count($friends); $i ++) {
                    if (($i >= $startElement && $i <= $endElement) || $endElement == 0) {
                        $uids[] = $friends[$i];
                        SGN_Log::writeLog(__CLASS__, __FUNCTION__, $uids);
                    }
                }
            }
            $this->_model = Application_Model_Armory_Gunny::factory('General');
            $zm_User = new ZME_User($config);
            $users = array();
            if (count($uids)) {
                $getUidPart = array();
                foreach ($uids as $uid) {
                    $userInfo = $this->_model->getZingMeUserInfo($uid);
                    if (! $userInfo) {
                        $getUidPart[] = $uid;
                    } else {
                        $users[] = $userInfo;
                    }
                }
            }
            if (count($getUidPart)) {
                $user = $zm_User->getInfo($access_token, $getUidPart, $fields = "id,username,displayname,tinyurl,profile_url,gender");
            }
            if (count($user)) {
                foreach ($user as $userData) {
                    $this->_model->setZingMeUserInfo($userData);
                }
                $users = array_merge($users, $user);
            }
            SGN_Log::writeLog(__CLASS__, __FUNCTION__, 'Output: ' . count($users));
            SGN_Log::writeLog(__CLASS__, __FUNCTION__, date('H:i:s d-m', time()) . ":" . 'total time = ' . (microtime(true) - $timeStart) * 1000);
            $result[0] = 1;
            $result[1] = $users;
            return $result;
        } catch (ZingMeApiException $Ze) {
            $result[0] = - 2;
            $result[1] = $Ze->getErrMsg();
            SGN_Log::writeLog(__CLASS__, __FUNCTION__, 'Output: ' . $Ze->getErrMsg());
            return $result;
        }
    }
    public function getTotalZingMeFriend ($access_token, $userID, $zingMeParam, $authorization_code = '', $signed_request = '')
    {
        $timeStart = microtime(true);
        $config = array('appname' => $zingMeParam['appname'], 'apikey' => $zingMeParam['apikey'], 'secretkey' => $zingMeParam['secretkey'], 'env' => $zingMeParam['env']);
        //$authorization_code = urldecode($authorization_code);
        try {
            $this->_model = Application_Model_Armory_Gunny::factory('General');
            $zm_Me = new ZME_Me($config);
            SGN_Log::writeLog(__CLASS__, __FUNCTION__, 'get zingme info - input:' . $access_token);
            $friends = $this->_model->getZingMeFriendID($userID);
            if (! $friends) {
                $friends = $zm_Me->getFriends($access_token);
                $this->_model->setZingMeFriendID($userID, $friends, 'notsave');
            }
            return $friends;
        } catch (ZingMeApiException $Ze) {
            if ($Ze->getCode() === - 13 || $Ze->getCode() === - 12) {
                if ($authorization_code) {
                    $access_token_data = $this->getAccessTokenByAuthorizationCode($authorization_code, $userID, $zingMeParam, false);
                    $access_token = $access_token_data['access_token'];
                } else {
                    $access_token_data = $this->getAccessTokenBySignedRequest($signed_request, $userID, $zingMeParam, false);
                    $access_token = $access_token_data;
                }
                $this->_model->setZingMeAccessToken($userID, $access_token_data);
                $friends = $zm_Me->getFriends($access_token);
                return $friends;
            }
            $result[0] = - 2;
            if (intval($Ze->getErrType())) {
                $result[1] = $Ze->getErrMsg();
            } else {
                $result[1] = $Ze->getErrType();
            }
            SGN_Log::writeLog(__CLASS__, __FUNCTION__ . 'Error', 'Error: ' . $Ze);
            SGN_Log::writeLog(__CLASS__, __FUNCTION__ . 'Error', 'IP: ' . $_SERVER['REMOTE_ADDR']);
            return $result;
        }
    }
    public function getAccessTokenBySignedRequest ($signed_request, $userID, $zingMeParam)
    {
        $timeStart = microtime(true);
        $config = array('appname' => $zingMeParam['appname'], 'apikey' => $zingMeParam['apikey'], 'secretkey' => $zingMeParam['secretkey'], 'env' => $zingMeParam['env']);
        $zm_Me = new ZME_Me($config);
        $error = array();
        $error['error']['type'] = '';
        $error['error']['url'] = '';
        $this->_model = Application_Model_Armory_Gunny::factory('General');
        //$authorization_code = urldecode($authorization_code);
        try {
            $access_token_data = $this->_model->getZingMeAccessToken($userID);
            $access_token = $access_token_data['access_token'];
            if (! $access_token) {
                $access_token = $zm_Me->getAccessTokenFromSignedRequest($signed_request);
                $access_token_data['expires'] = 7200;
                $access_token_data['access_token'] = $access_token;
                $this->_model->setZingMeAccessToken($userID, $access_token_data);
            }
            // @TODO remove line below
            //            $me = $zm_Me->getInfo($access_token);
            SGN_Log::writeLog(__CLASS__, __FUNCTION__, date('H:i:s d-m', time()) . ":" . 'total time = ' . (microtime(true) - $timeStart) * 1000);
            return $access_token;
        } catch (ZingMeApiException $Ze) {
            pr($Ze);
            if ($Ze->getCode() === - 13 || $Ze->getCode() === - 12) {
                try {
                    $access_token = $zm_Me->getAccessTokenFromSignedRequest($signed_request);
                    $access_token_data['expires'] = 7200;
                    $access_token_data['access_token'] = $access_token;
                    $this->_model->setZingMeAccessToken($userID, $access_token_data);
                } catch (ZingMeApiException $Ze) {
                    SGN_Log::writeLog(__CLASS__, __FUNCTION__, 'Output: ' . $Ze->getErrMsg());
                }
                return $access_token;
            }
            $result[0] = - 2;
            if (intval($Ze->getErrType())) {
                $result[1] = $Ze->getErrMsg();
            } else {
                $result[1] = $Ze->getErrType();
            }
            $result[2] = $Ze->getMessage();
            $result[3] = array($signed_request);
            SGN_Log::writeLog(__CLASS__, __FUNCTION__ . 'Error', 'Error: ' . $Ze);
            SGN_Log::writeLog(__CLASS__, __FUNCTION__ . 'Error', 'IP: ' . $_SERVER['REMOTE_ADDR']);
            return $result;
        }
    }
    public function getAccessTokenByAuthorizationCode ($authorization_code, $userID, $zingMeParam, $getCache = true)
    {
        $timeStart = microtime(true);
        $config = array('appname' => $zingMeParam['appname'], 'apikey' => $zingMeParam['apikey'], 'secretkey' => $zingMeParam['secretkey'], 'env' => $zingMeParam['env']);
        $zm_Me = new ZME_Me($config);
        $error = array();
        $error['error']['type'] = '';
        $error['error']['url'] = '';
        $this->_model = Application_Model_Armory_Gunny::factory('General');
        try {
            if ($getCache) {
                $access_token_data = $this->_model->getZingMeAccessToken($userID);
            }
            if (! $access_token_data) {
                $access_token_data = $zm_Me->getAccessTokenFromCode($authorization_code);
                $this->_model->setZingMeAccessToken($userID, $access_token_data);
            }
            SGN_Log::writeLog(__CLASS__, __FUNCTION__, $authorization_code);
        } catch (ZingMeApiException $Ze) {
            SGN_Log::writeLog(__CLASS__, __FUNCTION__ . 'Error', 'error: ' . $Ze->getErrMsg());
            if ($Ze->getErrType() === - 1 && $Ze->getErrMsg() !== 'Error validating application.') {
                $state = rand(1, 10000000);
                $url = $zm_Me->getUrlAuthorized($zingMeParam['redirectUri'] . '?env=' . $zingMeParam['envRedirect'] . '&userid=' . $userID . "&update=true", $state);
                SGN_Log::writeLog(__CLASS__, __FUNCTION__, $authorization_code);
                echo "
                <script type=\"text/javascript\">
                    document.domain = 'zing.vn';
                	tb_show(\"Sign in\",\"$url&KeepThis=true&TB_iframe=true&height=350&width=520\");
				</script>";
            } else {
                return;
            }
        }
        if ($access_token_data != null) {
            $access_token = $access_token_data['access_token'];
        }
        return $access_token;
    }
}



